package com.my.lab.net;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import com.my.lab.util.ConfigConstant;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

/**
 * 
 * 监听广播线程
 * 
 * @author Administrator
 * 
 */
public class NetMonitorThread implements Runnable {

    private static NetMonitorThread instance;

    private Thread udpThread = null;

    private final static String TAG = "NetMonitorThread";

    private static final int BUFFERLENGTH = 1024; // 缓冲大小

    private boolean onWork = false; // 线程工作标识

    private DatagramSocket udpSocket = null; // 用于接收和发送udp数据的socket

    private DatagramPacket udpSendPacket = null; // 用于发送的udp数据包

    private DatagramPacket udpResPacket = null; // 用于接收的udp数据包

    private byte[] resBuffer = new byte[BUFFERLENGTH]; // 接收数据的缓存

    private byte[] sendBuffer = null;
    
    private Handler mhandler ;

    public static NetMonitorThread newInstance() {
        if (instance == null) {
            return new NetMonitorThread();
        }
        return instance;
    }

    private void stopThread() {
        onWork = false;
        if (udpThread != null)
            udpThread.interrupt();
        Log.i(TAG, "停止监听UDP数据");
    }

    private void startThread() {
        if (udpThread == null) {
            udpThread = new Thread(this);
            udpThread.start();
            Log.i(TAG, "正在监听UDP数据");
        }

    }

    /**
     * 停止监听UDP数据
     */
    public void disconnectSocket() {
        onWork = false; // 设置线程运行标识为不运行
        stopThread();
    }

    private synchronized void sendUdpData(String data, InetAddress sendTo, int port , Handler mhandler) {
        try {
            sendBuffer = data.getBytes("gbk");
            udpSendPacket = new DatagramPacket(sendBuffer, 0, sendBuffer.length, sendTo, port);
            udpSocket.send(udpSendPacket);
            if(mhandler != null) {
                mhandler.obtainMessage(0, sendTo).sendToTarget();
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 监听端口，接收UDP数据
     * 
     * @return
     */
    public boolean connectSocket(Handler callBack) {
        this.mhandler = callBack;
        boolean result = false;
        try {
            if (udpSocket == null) {
                udpSocket = new DatagramSocket(ConfigConstant.UDP_BOADCASTPORT); // 绑定端口
                Log.i(TAG, "connectSocket()....绑定UDP端口" + ConfigConstant.UDP_BOADCASTPORT + "成功");
            }
            if (udpResPacket == null)
                udpResPacket = new DatagramPacket(resBuffer, BUFFERLENGTH);
            onWork = true; // 设置标识为线程工作
            startThread(); // 启动线程接收udp数据
            result = true;
        } catch (SocketException e) {
            e.printStackTrace();
            disconnectSocket();
            Log.e(TAG, "connectSocket()....绑定UDP端口" + ConfigConstant.UDP_BOADCASTPORT + "失败");
        }

        return result;
    }

    @Override
    public void run() {
        while (onWork) {

            try {
                udpSocket.receive(udpResPacket);
            } catch (IOException e) {
                onWork = false;
                if (udpResPacket != null) {
                    udpResPacket = null;
                }
                if (udpSocket != null) {
                    udpSocket.close();
                    udpSocket = null;
                }
                udpThread = null;
                Log.e(TAG, "UDP数据包接收失败！线程停止");
                break;
            }
            if(udpResPacket.getLength() == 0){
                Log.i(TAG, "无法接收UDP数据或者接收到的UDP数据为空");
                continue;
            }
            String ipmsgStr = "";
            try {
                ipmsgStr = new String(resBuffer, 0, udpResPacket.getLength(),"gbk");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
                Log.e(TAG, "接收数据时，系统不支持GBK编码");
            }
            Log.i(TAG, "接收到的UDP数据内容为:" + ipmsgStr);
            sendUdpData("roger", udpResPacket.getAddress(), ConfigConstant.UDP_SEND , mhandler);
            if(udpResPacket != null){   //每次接收完UDP数据后，重置长度。否则可能会导致下次收到数据包被截断。
                udpResPacket.setLength(BUFFERLENGTH);
            }
            this.disconnectSocket();
        }
        if(udpResPacket != null)
            udpResPacket = null ;
        if(udpSocket != null) {
            udpSocket.close();
            udpSocket = null ;
        }
        udpThread = null ;
    }

}
